/* Copyright (c) 2015 Slava Naumenko - http://m4w.codeplex.com */

using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace M4W.ASM.Services
{
    [Guid("96dc4f13-f060-4277-a6e5-8ec326473379")]
    public class WebConfMod : SPFeatureReceiver
    {
        private const string Owner = "M4W.ASM.Services";
        private const string Namespace = "M4W.ASM.Services";

        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            List<SPWebConfigModification> webConfMods = new List<SPWebConfigModification>();
            webConfMods.Add(GetAuthorizedTypeWebConfigMod(typeof(WebConfMod)));
            webConfMods.Add(GetWebConfigNode("Calendar.asmx"));
            webConfMods.Add(GetWebConfigNode("Document.asmx"));
            webConfMods.Add(GetWebConfigNode("Email.asmx"));
            webConfMods.Add(GetWebConfigNode("Group.asmx"));
            webConfMods.Add(GetWebConfigNode("List.asmx"));
            webConfMods.Add(GetWebConfigNode("Query.asmx"));
            webConfMods.Add(GetWebConfigNode("Site.asmx"));
            webConfMods.Add(GetWebConfigNode("Text.asmx"));
            webConfMods.Add(GetWebConfigNode("Web.asmx"));

            SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;

            foreach (var webConfMod in webConfMods)
            {
                parentWebApp.WebConfigModifications.Add(webConfMod);
            }

            parentWebApp.Update();
            parentWebApp.WebService.ApplyWebConfigModifications();
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;

            List<SPWebConfigModification> webConfModsToRemove = new List<SPWebConfigModification>();
            foreach (SPWebConfigModification webConfMod in parentWebApp.WebConfigModifications)
            {
                if (webConfMod.Owner == Owner)
                {
                    webConfModsToRemove.Add(webConfMod);
                }
            }

            foreach (SPWebConfigModification webConfMod in webConfModsToRemove)
            {
                parentWebApp.WebConfigModifications.Remove(webConfMod);
            }

            parentWebApp.Update();
            parentWebApp.WebService.ApplyWebConfigModifications();
        }

        private SPWebConfigModification GetAuthorizedTypeWebConfigMod(Type owner)
        {
            string assemblyFullName = owner.Assembly.FullName.ToString();

            SPWebConfigModification webConfMod = new SPWebConfigModification();
            webConfMod.Owner = Owner;
            webConfMod.Sequence = 1000;
            webConfMod.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
            webConfMod.Path = "configuration/System.Workflow.ComponentModel.WorkflowCompiler/authorizedTypes/targetFx";
            webConfMod.Name = String.Format("authorizedType[@Assembly='{0}'][@Namespace='{1}'][@TypeName='{2}'][@Authorized='True']", assemblyFullName, Namespace, "*");
            webConfMod.Value = String.Format("<authorizedType Assembly='{0}' Namespace='{1}' TypeName='{2}' Authorized='True' />", assemblyFullName, Namespace, "*");

            return webConfMod;
        }

        private SPWebConfigModification GetWebConfigNode(string uri)
        {
            SPWebConfigModification webConfMod = new SPWebConfigModification();
            webConfMod.Owner = Owner;
            webConfMod.Sequence = 0;
            webConfMod.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
            webConfMod.Path = "configuration";
            webConfMod.Name = String.Format("location[@path='_layouts/15/M4W.ASM.Services/{0}']", uri);
            webConfMod.Value = String.Format("<location path='_layouts/15/M4W.ASM.Services/{0}'><system.web><httpRuntime maxRequestLength='2097151' executionTimeout='3600' /><webServices><protocols><add name='HttpSoap12'/><add name='HttpSoap'/><add name='HttpGet'/><add name='HttpPost'/></protocols></webServices></system.web></location>", uri);

            return webConfMod;
        }
    }
}
